package viper.GUI;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import javax.swing.border.Border;

import viper.main.StateManager;

/**
 * @author Kevin Sin
 * 
 * Revision number: 1
 * Date created: 1/17/10
 * Date of Last Back-up on SVN: none
 * 
 * <p>This class is responsible for the GUI.  It interacts w/ StateManger only
 * to display the right info to the user and responds to user actions.  A CardLayout
 * is used to develop different panels and integrate them easily.
 */
public class ViperGUI extends JFrame{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	//Singleton structure.
	public final static ViperGUI INSTANCE = new ViperGUI();

	public static final String LOGGED_OUT_CARD = "LOGGED_OUT_CARD";
	public static final String LOGGED_IN_CARD = "LOGGED_IN_CARD";
	public static final String CALL_SENDER_SETUP_CARD = "CALL_SENDER_SETUP_CARD";
	public static final String IN_CALL_CARD = "IN_CALL_CARD";
	
	private JPanel cardPanel;
	private CardLayout cl;
	
	private LoggedInPanel loggedInPanel;
	private LoggedOutPanel loggedOutPanel;
	private InCallPanel inCallPanel;
	private CallSenderSetupPanel callSenderSetupPanel;
	
	private JInternalFrame internalFrame;
	private JPanel framePanel;

	public JInternalFrame getInternalFrame() {
		return internalFrame;
	}
	
	public JPanel getFramePanel() {
		return framePanel;
	}
	
	public InCallPanel getInCallPanel()
	{
		return inCallPanel;
	}

	private ViperGUI() {
		
		getContentPane().setBackground(new Color(255, 255, 255));

		setTitle("VIPER");
		setLayout(new BorderLayout());

		cardPanel = new JPanel();

		cl = new CardLayout();
		cardPanel.setLayout(cl);
		cardPanel.setBackground(new Color(255, 255, 255));

		loggedInPanel = new LoggedInPanel();
		loggedInPanel.setBackground(new Color(255, 255, 255));
		
		loggedOutPanel = new LoggedOutPanel();
		loggedOutPanel.setBackground(new Color(255, 255, 255));
		
		inCallPanel = new InCallPanel();
		inCallPanel.setBackground(new Color(255, 255, 255));
		
		callSenderSetupPanel = new CallSenderSetupPanel();
		callSenderSetupPanel.setBackground(new Color(255, 255, 255));
		
		internalFrame = new JInternalFrame("title", false, false, false);
		//internalFrame.setSize(0, 0);
		
		//internalFrame.setMinimumSize(new Dimension(500, 150));
		
		framePanel = new JPanel();
		framePanel.setBackground(new Color(255, 255, 255));
		internalFrame.add(framePanel);
		
		Border padding = BorderFactory.createEmptyBorder(10,10,10,10);
		cardPanel.setBorder(padding);
		
		cardPanel.add(loggedInPanel, LOGGED_IN_CARD);
		cardPanel.add(loggedOutPanel, LOGGED_OUT_CARD);
		cardPanel.add(inCallPanel, IN_CALL_CARD);
		cardPanel.add(callSenderSetupPanel, CALL_SENDER_SETUP_CARD);

		getContentPane().add(cardPanel, BorderLayout.CENTER);
		
		//internalFrame.setLayer(JLayeredPane.PALETTE_LAYER);
		getContentPane().add(internalFrame, BorderLayout.PAGE_END);
		
		//cardPanel.add(internalFrame, BorderLayout.PAGE_END);
	
	}

	/**
	 * Sets the size and displays the window.
	 */
	public void initialize(){
		
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setResizable(false);
		changeCard(LOGGED_OUT_CARD);
		setVisible(true);
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				StateManager.INSTANCE.exit();
			}			
		});	 
		
		setIconImage(new ImageIcon("images/icon.gif").getImage());
	}
	
	/**
	 * @param cardName - which JPanel to display
	 * Changes the window title and updates each panel before showing that panel.
	 */
	public void changeCard(String cardName){
		//StateManager.INSTANCE.updatePeers();
		if(cardName.equals(LOGGED_OUT_CARD))
		{
			
			setSize(500, 500);
			setTitle("VIPER - Logged Out");
		}
		else if(cardName.equals(LOGGED_IN_CARD))
		{
			//internalFrame.setSize(500, 150);
			setSize(500, 600);
			internalFrame.setVisible(false);
			StateManager.INSTANCE.updatePeers();
			setTitle("VIPER - Logged In as " + StateManager.INSTANCE.getUsername());
			loggedInPanel.update();
		}
		else if(cardName.equals(CALL_SENDER_SETUP_CARD))
		{
			//internalFrame.setSize(500, 150);
			setSize(500, 600);
			StateManager.INSTANCE.updatePeers();
			setTitle("VIPER - Call Setup to Talk to " + StateManager.INSTANCE.getCalleeArray()[1]);
			callSenderSetupPanel.update();
		}
		else if(cardName.equals(IN_CALL_CARD))
		{
			//internalFrame.setSize(0, 0);
			internalFrame.setVisible(false);
			setSize(900, 600);
			StateManager.INSTANCE.updatePeers();
			setTitle("VIPER - In Call");
			inCallPanel.update();
		}	
		cl.show(cardPanel, cardName);
		repaint();
	}
	
	/**
	 * For displaying internal frame when transitioning to DIALING
	 */
	public void changeInternalFrameDialing()
	{
		internalFrame.setTitle("Dialing");
		framePanel.removeAll();
		framePanel.setLayout(new FlowLayout());
		JButton button = new JButton("Cancel");
		final String calleeIP = (String)(StateManager.INSTANCE.getCalleeArray()[0]);
		String calleeName = (String)StateManager.INSTANCE.getCalleeArray()[1];
		button.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				StateManager.INSTANCE.cancelCall(calleeIP);
			}
        });
		framePanel.add(button);
		framePanel.add(new JLabel("Dialing " + calleeName + " (" + calleeIP + ")"));
		internalFrame.setVisible(true);
	}
	
	/**
	 * For displaying internal frame when transitionoing to CALL_DECISION
	 */
	public void changeInternalFrameCallDecision(final String sourceAddrIP, final byte typeCode, final String[] relays)
	{
		String name = (String)StateManager.INSTANCE.getPeerRowFromIP(sourceAddrIP)[1];
		internalFrame.setTitle(name + " (" + sourceAddrIP + 
			") wants to talk to you!");
		framePanel.removeAll();
		framePanel.setLayout(new FlowLayout());
		
		JButton acceptButton = new JButton("Accept");
		acceptButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				StateManager.INSTANCE.acceptCall(sourceAddrIP, typeCode, relays);
			}
		});
		JButton rejectButton = new JButton("Reject");
		rejectButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				StateManager.INSTANCE.rejectCall(sourceAddrIP, typeCode, relays);
			}
		});
		framePanel.add(acceptButton);
		framePanel.add(rejectButton);
		internalFrame.setVisible(true);
	}
	
	public void showReceiverStatsBegin()
	{
		framePanel.removeAll();
		internalFrame.setVisible(true);
	}
	
	public void showReceiverStatsEnd()
	{
		internalFrame.setVisible(false);
	}
}
